package jee.boot.entity.auth;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jee.boot.common.annotation.Column;
import jee.boot.common.annotation.Table;
import jee.boot.common.annotation.Transient;
import jee.boot.common.utils.StringUtils;
import jee.boot.entity.system.BasicSbj;
import jee.boot.entity.system.Filter;
import org.assertj.core.util.Sets;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 用户
 */
@Table(name = "at_user")
public class User extends BasicSbj<User> {

    private static final long serialVersionUID = 1L;
    /**
     * 用户操作状态
     */
    @Column(name = "st_user_operation_status")
    private String userOperationStatus;//字典：DIC_AUTH_UserOperationStatus
    /**
     * 姓
     */
    @Column(name = "st_user_last_name")
    private String userLastName;//文本
    /**
     * 名
     */
    @Column(name = "st_user_first_name")
    private String userFirstName;//文本
//
//    /**
//     * 电子邮件
//     */
//    @Column(name = "st_email")
//    private String email;//文本
//    /**
//     * 电话
//     */
//    @Column(name = "st_phone")
//    private String phone;//文本
    /**
     * 性别
     */
    @Column(name = "st_gender")
    private String gender;//字典：DIC_SYS_GENDER
    /**
     * 组织的默认管理员标志
     */
    @Column(name = "st_org_default_admin_flag")
    private String orgDefaultAdminFlag;//字典：DIC_SYS_YesNo，针对供应商用户默认用于表达“当前用户是否为供应商的默认管理员”的含义
    /**
     * 拥有者模型
     */
    @Column(name = "st_owner_model")
    private String ownerModel;//模型，此处OWNER是类似MT_EMPLOYEE表内OWNER的功能，考虑到不是所有的USER都有EMPLOYEE对应，所以这里要冗余存储一份。注意，此OWNER代表的是所属的供应商、部门，而不是员工。
    /**
     * 拥有者ID
     */
    @Column(name = "st_owner_id")
    private String ownerId;//模型引用，参见ST_OWNER_MODEL字段注释。
    /**
     * GDPR删除标志
     */
    @Column(name = "st_gdpr_del_flag")
    private String gdprDelFlag;//字典：DIC_SYS_YesNo
    /**
     * 登录账号id
     */
    @Column(name = "st_account_id", data = {"account.id", "account.username", "account.phone", "account.email", "account.accountStatus", "account.resetPassword", "account.passwordErrors", "account.passwordInvalidDate", "account.accountInvalidDate", "account.status", "account.name"})
    private Account account = new Account();
    /**
     * 拥有者对象,比如 employee,supplier,customer等,与ownerId配合使用
     */
    @Transient
    private Object owner;
    /**
     * 当前用户拥有的组
     */
    @Transient
    private List<Group> groupList = Lists.newArrayList();
    /**
     * 当前用户拥有的角色
     */
    @Transient
    private List<Role> roleList = Lists.newArrayList();
    /**
     * 所有的模型权限
     */
    @Transient
    private List<AuthEntity>modelAuthList=Lists.newArrayList();
    /**
     * 对应到account.username属性.伪列
     */
    @Transient
    private String username;
    public User() {
        super();
        setCacheKey(getProjectConfig().getName() + "_user");
    }

    public User(String id) {
        super(id);
        setCacheKey(getProjectConfig().getName() + "_user");
    }

    public User(Account account) {
        this.account = account;
    }

    public String getUserOperationStatus() {
        return userOperationStatus;
    }

    public void setUserOperationStatus(String userOperationStatus) {
        this.userOperationStatus = userOperationStatus;
    }

    public String getUserLastName() {
        return userLastName;
    }

    public void setUserLastName(String userLastName) {
        this.userLastName = userLastName;
    }

    public String getUserFirstName() {
        return userFirstName;
    }

    public void setUserFirstName(String userFirstName) {
        this.userFirstName = userFirstName;
    }


//    public String getEmail() {
//        return email;
//    }
//
//    public void setEmail(String email) {
//        this.email = email;
//    }
//
//    public String getPhone() {
//        return phone;
//    }
//
//    public void setPhone(String phone) {
//        this.phone = phone;
//    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getOrgDefaultAdminFlag() {
        return orgDefaultAdminFlag;
    }

    public void setOrgDefaultAdminFlag(String orgDefaultAdminFlag) {
        this.orgDefaultAdminFlag = orgDefaultAdminFlag;
    }

    public String getOwnerModel() {
        return ownerModel;
    }

    public void setOwnerModel(String ownerModel) {
        this.ownerModel = ownerModel;
    }

    public String getOwnerId() {
        return ownerId;
    }

    public void setOwnerId(String ownerId) {
        this.ownerId = ownerId;
    }

    public String getGdprDelFlag() {
        return gdprDelFlag;
    }

    public void setGdprDelFlag(String gdprDelFlag) {
        this.gdprDelFlag = gdprDelFlag;
    }

    public Account getAccount() {
        return account;
    }

    public void setAccount(Account account) {
        this.account = account;
    }

    public List<Group> getGroupList() {
        return groupList;
    }

    public void setGroupList(List<Group> groupList) {
        this.groupList = groupList;
    }

    public List<Role> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<Role> roleList) {
        this.roleList = roleList;
    }

    public Object getOwner() {
        return owner;
    }

    public void setOwner(Object owner) {
        this.owner = owner;
    }
/**----------------------------辅助数据-------------------------------*/
    /**
     * 当前用户所有的请求权限
     * <request.id,request>
     */
    @Transient
    private Map<String, Resource> requestMap = Maps.newHashMap();
    /**
     * 当前用户拥有的角色(包含组内的角色,汇总后去重)
     */
    @Transient
    private Set<Role> roleSet = Sets.newHashSet();
    /**
     * 当前用户拥有的资源(包含所有原子权限内的资源,汇总后去重,initData时候给前端渲染菜单使用)
     */
    @Transient
    private Set<Resource> resourceSet = Sets.newHashSet();
    /**
     * 当前用户拥有的权限集合
     */
    @Transient
    private Set<Authority> authoritySet = Sets.newHashSet();
    /**
     * 根据请求的path来缓存用户的数据过滤规则
     * <url(request.name),List<RowSet>>
     */
    @Transient
    private Map<String, List<AuthEntity>> rowSetByPathMap = Maps.newHashMap();

    @JsonIgnore
    public Set<Role> getRoleSet() {
        return roleSet;
    }

    public void setRoleSet(Set<Role> roleSet) {
        this.roleSet = roleSet;
    }

    @JsonIgnore
    public Set<Resource> getResourceSet() {
        return resourceSet;
    }

    public void setResourceSet(Set<Resource> resourceSet) {
        this.resourceSet = resourceSet;
    }

    @JsonIgnore
    public Map<String, Resource> getRequestMap() {
        return requestMap;
    }

    public void setRequestMap(Map<String, Resource> requestMap) {
        this.requestMap = requestMap;
    }

    @JsonIgnore
    public Set<Authority> getAuthoritySet() {
        return authoritySet;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * 读取当前用户的所有定义的模型,包含重复的,全局的,请求私有的模型定义
     *
     * @return
     */
    @JsonIgnore
    public List<AuthEntity> getModelDataList() {
        Set<Authority> authoritySet = getAuthoritySet();
        List<AuthEntity> listAuthEntity = Lists.newArrayList();
        if (!authoritySet.isEmpty()) {
            authoritySet.stream()
                    .forEach(d -> {
                        listAuthEntity.addAll(d.getModelList());
                    });
        }
        return listAuthEntity;
    }

    /**
     * 读取当前用户的所有定义的RowSet
     *
     * @return
     */
    @JsonIgnore
    public List<AuthEntity> getRowSetList() {
        Set<Authority> authoritySet = getAuthoritySet();
        List<AuthEntity> listAuthEntity = Lists.newArrayList();
        if (!authoritySet.isEmpty()) {
            authoritySet.stream()
                    .forEach(d -> {
                        listAuthEntity.addAll(d.getRowSetList());
                    });
        }
        return listAuthEntity;
    }
    /**
     * 读取当前用户的所有定义的Column
     *
     * @return
     */
    @JsonIgnore
    public List<AuthEntity> getColumnList() {
        Set<Authority> authoritySet = getAuthoritySet();
        List<AuthEntity> listAuthEntity = Lists.newArrayList();
        if (!authoritySet.isEmpty()) {
            authoritySet.stream()
                    .forEach(d -> {
                        listAuthEntity.addAll(d.getColumnList());
                    });
        }
        return listAuthEntity;
    }
    /**
     * 读取当前用户的所有定义的CellSet
     *
     * @return
     */
    @JsonIgnore
    public List<AuthEntity> getCellSetList() {
        Set<Authority> authoritySet = getAuthoritySet();
        List<AuthEntity> listAuthEntity = Lists.newArrayList();
        if (!authoritySet.isEmpty()) {
            authoritySet.stream()
                    .forEach(d -> {
                        listAuthEntity.addAll(d.getCellSetList());
                    });
        }
        return listAuthEntity;
    }

    public void setAuthoritySet(Set<Authority> authoritySet) {
        this.authoritySet = authoritySet;
    }

    public List<AuthEntity> getModelAuthList() {
        return modelAuthList;
    }

    public void setModelAuthList(List<AuthEntity> modelAuthList) {
        this.modelAuthList = modelAuthList;
    }

    /**
     * 将原子权限聚合里的权限配置分解到用户中冗余存储
     * @param authority
     */
    public void addAuthorityPermission(Authority authority) {
        this.getAuthoritySet().add(authority);
        List<AuthEntity> modelList = authority.getModelList();
        List<AuthEntity> columnList = authority.getColumnList();
        List<AuthEntity> rowSetList = authority.getRowSetList();
        List<AuthEntity> cellSetList = authority.getCellSetList();
        if(!modelList.isEmpty()){
            modelList.forEach(modelAuth->{
                getModelAuthList().add(modelAuth);
                addColumnAuth2Model(columnList,modelAuth);
                addRowSetAuth2Model(rowSetList,modelAuth);
                addCellSetAuth2Model(cellSetList,modelAuth);
            });
        }

    }

    /**
     * 添加columnList数据到modelData中
     * @param columnList
     * @param modelAuth
     */
    private void addColumnAuth2Model(List<AuthEntity> columnList, AuthEntity modelAuth) {
        String controlDomainType = modelAuth.getControlDomainType();
        String modelKey=modelAuth.getEntityId();
        boolean qj=true;//全局model
        if(!StringUtils.equals("DIC_AUTH_ControlDomainType_CDT01",controlDomainType)){
            qj=false;
        }
        if(!qj){
            modelKey=modelKey+"_"+modelAuth.getControlDomain().getId();
        }
        if(columnList!=null && !columnList.isEmpty()){
            for(AuthEntity columnAuth:columnList){
                String columnKey=((jee.boot.entity.auth.Column)columnAuth.getEntity()).getModelData().getId();
                if(!qj){
                    columnKey=columnKey+"_"+columnAuth.getControlDomain().getId();
                }
                if(StringUtils.equals(modelKey,columnKey)){
                    ModelData modelData = (ModelData)modelAuth.getEntity();
                    modelData.getColumnAuthList().add(columnAuth);
                }
            }
        }
    }
    /**
     * 添加rowSetList数据到modelData中
     * @param rowSetList
     * @param modelAuth
     */
    private void addRowSetAuth2Model(List<AuthEntity> rowSetList, AuthEntity modelAuth) {
        String controlDomainType = modelAuth.getControlDomainType();
        String modelKey=modelAuth.getEntityId();
        boolean qj=true;//全局model
        if(!StringUtils.equals("DIC_AUTH_ControlDomainType_CDT01",controlDomainType)){
            qj=false;
        }
        if(!qj){
            modelKey=modelKey+"_"+modelAuth.getControlDomain().getId();
        }
        if(rowSetList!=null && !rowSetList.isEmpty()){
            for(AuthEntity rowSetAuth:rowSetList){
                String rowSetKey=((RowSet)rowSetAuth.getEntity()).getModelData().getId();
                if(!qj){
                    rowSetKey=rowSetKey+"_"+rowSetAuth.getControlDomain().getId();
                }
                if(StringUtils.equals(modelKey,rowSetKey)){
                    ModelData modelData = (ModelData)modelAuth.getEntity();
                    modelData.getRowSetAuthList().add(rowSetAuth);
                }
            }
        }
    }
    /**
     * 添加cellSetList数据到modelData中
     * @param cellSetList
     * @param modelAuth
     */
    private void addCellSetAuth2Model(List<AuthEntity> cellSetList, AuthEntity modelAuth) {
        String controlDomainType = modelAuth.getControlDomainType();
        String modelKey=modelAuth.getEntityId();
        boolean qj=true;//全局model
        if(!StringUtils.equals("DIC_AUTH_ControlDomainType_CDT01",controlDomainType)){
            qj=false;
        }
        if(!qj){
            modelKey=modelKey+"_"+modelAuth.getControlDomain().getId();
        }
        if(cellSetList!=null && !cellSetList.isEmpty()){
            for(AuthEntity cellSetAuth:cellSetList){
                String cellSetKey=((CellSet)cellSetAuth.getEntity()).getModelData().getId();
                if(!qj){
                    cellSetKey=cellSetKey+"_"+cellSetAuth.getControlDomain().getId();
                }
                if(StringUtils.equals(modelKey,cellSetKey)){
                    ModelData modelData = (ModelData)modelAuth.getEntity();
                    modelData.getCellSetAuthList().add(cellSetAuth);
                }
            }
        }
    }

    public static void main(String[] args) {
        User user =new User();
        user.addFilter(new Filter("account.id", "=", "123"));
        System.out.println(user.getFindListSql()+"where "+user.getWhere()+" "+user.getOrderBySql());
    }
}